import { getStorage } from './storage';

// 请求拦截器类型
export type RequestInterceptor = (config: HttpConfig) => HttpConfig | Promise<HttpConfig>;

// 响应拦截器类型
export type ResponseInterceptor = <T = any>(response: HttpResponse<T>) => HttpResponse<T> | Promise<HttpResponse<T>>;

// 请求配置
export interface RequestConfig {
  url?: string;
  method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'CONNECT' | 'TRACE';
  data?: any;
  header?: Record<string, string>;
  timeout?: number;
  dataType?: string;
  responseType?: 'text' | 'arraybuffer';
  withCredentials?: boolean;
}

// 响应结构
export interface HttpResponse<T = any> {
  data: T;
  statusCode: number;
  header: any;
  cookies: any[];
  config: HttpConfig; // 新增: 添加 config 属性
}

// 定义请求配置接口
export interface HttpConfig extends UniApp.RequestOptions {
  baseURL?: string;
  timeout?: number;
  headers?: Record<string, string>;
  cache?: boolean;
}

// 定义响应结构
export interface HttpResponse<T = any> {
  data: T;
  statusCode: number;
  header: any;
  cookies: any[];
}

// 错误处理类
export class HttpError extends Error {
  constructor(public message: string, public status: number, public response?: HttpResponse) {
    super(message);
    this.name = 'HttpError';
  }
}

export class Http {
  private config: HttpConfig;
  private requestInterceptors: RequestInterceptor[] = [];
  private responseInterceptors: ResponseInterceptor[] = [];

  constructor(config: HttpConfig = {} as HttpConfig) {
    this.config = {
      baseURL: '',
      timeout: 10000,
      headers: {
        'Content-Type': 'application/json',
      },
      ...config,
    };
  }

  // 添加请求拦截器
  useRequestInterceptor(interceptor: RequestInterceptor): void {
    this.requestInterceptors.push(interceptor);
  }

  // 添加响应拦截器
  useResponseInterceptor(interceptor: ResponseInterceptor): void {
    this.responseInterceptors.push(interceptor);
  }

  // 执行请求拦截器
  private async runRequestInterceptors(config: HttpConfig): Promise<HttpConfig> {
    let newConfig = { ...config };
    for (const interceptor of this.requestInterceptors) {
      newConfig = await interceptor(newConfig);
    }
    return newConfig;
  }

  // 执行响应拦截器
  private async runResponseInterceptors(response: HttpResponse): Promise<HttpResponse> {
    let newResponse = { ...response };
    for (const interceptor of this.responseInterceptors) {
      newResponse = await interceptor(newResponse);
    }
    return newResponse;
  }

  // 添加请求缓存
  requestCache = new Map<string, Promise<any>>();

  private async request<T = any>(config: HttpConfig): Promise<HttpResponse<T>> {
    const cacheKey = `${config.method}:${config.url}`;

    if (config.cache && this.requestCache.has(cacheKey)) {
      return this.requestCache.get(cacheKey)!;
    }

    const requestPromise = this._request<T>(config);

    if (config.cache) {
      this.requestCache.set(cacheKey, requestPromise);
    }

    return requestPromise;
  }

  // 核心请求方法
  private async _request<T = any>(config: HttpConfig): Promise<HttpResponse<T>> {
    // 合并全局配置
    const mergedConfig: HttpConfig = {
      ...this.config,
      ...config,
      header: {
        ...this.config.headers,
        ...config.headers,
      },
    };

    // 处理基础URL
    if (mergedConfig.baseURL && !mergedConfig.url?.startsWith('http')) {
      mergedConfig.url = mergedConfig.baseURL + mergedConfig.url;
    }

    // 执行请求拦截器
    const finalConfig = await this.runRequestInterceptors(mergedConfig);

    return new Promise((resolve, reject) => {
      // 创建取消令牌
      let aborted = false;
      const abortController = {
        abort: () => {
          aborted = true;
          reject(new HttpError('Request aborted', 0));
        },
      };

      // 设置超时
      let timer: ReturnType<typeof setTimeout> | null = null;
      if (finalConfig.timeout) {
        timer = setTimeout(() => {
          reject(new HttpError('Request timeout', 408));
          abortController.abort();
        }, finalConfig.timeout);
      }

      // 发起请求
      uni.request({
        ...finalConfig,
        success: async response => {
          if (timer) clearTimeout(timer);

          if (aborted) return;

          try {
            // 执行响应拦截器
            const processedResponse = await this.runResponseInterceptors(response as HttpResponse<T>);

            // 处理非200状态码
            if (response.statusCode < 200 || response.statusCode >= 300) {
              reject(
                new HttpError(
                  `Request failed with status code ${response.statusCode}`,
                  response.statusCode,
                  processedResponse,
                ),
              );
              return;
            }

            resolve(processedResponse);
          } catch (error) {
            reject(error);
          }
        },
        fail: error => {
          if (timer) clearTimeout(timer);
          reject(new HttpError(error.errMsg || 'Network Error', 0));
        },
      });
    });
  }

  // GET 请求
  public get<T = any>(url: string, config?: HttpConfig): Promise<HttpResponse<T>> {
    return this.request<T>({
      ...config,
      url,
      method: 'GET',
    });
  }

  // POST 请求
  public post<T = any>(url: string, data?: any, config?: HttpConfig): Promise<HttpResponse<T>> {
    return this.request<T>({
      ...config,
      url,
      data,
      method: 'POST',
    });
  }

  // PUT 请求
  public put<T = any>(url: string, data?: any, config?: HttpConfig): Promise<HttpResponse<T>> {
    return this.request<T>({
      ...config,
      url,
      data,
      method: 'PUT',
    });
  }

  // DELETE 请求
  public delete<T = any>(url: string, config?: HttpConfig): Promise<HttpResponse<T>> {
    return this.request<T>({
      ...config,
      url,
      method: 'DELETE',
    });
  }

  // 创建新实例
  public create(config: HttpConfig): Http {
    return new Http({
      ...this.config,
      ...config,
    });
  }
}

// 创建默认实例
export const http = new Http({
  url: '',
  baseURL: import.meta.env.VITE_API_BASE_URL || '/api', // 统一API前缀
  timeout: 15000,
});

export default http;

// 添加请求拦截器 - 示例
http.useRequestInterceptor(config => {
  // 添加认证令牌
  const token = getStorage('token')?.value;
  if (token) {
    config.header = config.header || {};
    config.header.Authorization = `Bearer ${token}`;
  }
  return config;
});

// 添加mock响应拦截器
// 修改后的响应拦截器示例
http.useResponseInterceptor(response => {
  // 示例mock数据
  if (response.config.url?.includes('/auth/wechat')) {
    return {
      ...response,
      data: {
        code: 0,
        data: {
          openid: 'mock_openid_' + Date.now(),
          token: 'mock_token_' + Date.now(),
          nickname: 'Mock用户',
          avatar: 'https://dummyimage.com/100x100/007AFF/fff',
        },
      },
    } as HttpResponse<any>;
  }

  // 其他接口mock示例
  if (response.config.url?.includes('/todos')) {
    return {
      ...response,
      data: {
        code: 0,
        data: response.data, // 正确使用已有数据作为mock返回
      },
    } as HttpResponse<any>;
  }

  return response;
});
